/**
 * \file re.h
 * \brief Some functions to construct regular expression NFA.
 **/

#ifndef R_RE_H
#define R_RE_H

#include "standard.h"
#include "nfa.h"
#include "value.h"

/* This is a subexpression of a regular expression. */
struct ReSubExpressionT {
  NFANode* input;
  NFANode* output; /* Linked list of output nodes */
};
typedef struct ReSubExpressionT ReSubExpression;

/**
 * \brief sub-expression := sub-expression | sub-expression
 **/
ReSubExpression r_re_alter(ReSubExpression first, ReSubExpression second);

/**
 * \brief Compile a regular expression into a NFA node graph. term_id is the
 * id that will be applied to the terminator state in the NFA.
 **/
NFANode* r_re_compile(char* expression, int term_id);

/**
 * \brief Connect the output of one ReSubExpression to the input of another.
 *     sub-expression := sub-expression sub-expression
 **/
ReSubExpression r_re_concat(ReSubExpression first, ReSubExpression second);

/**
 * \brief Construct a sub-expression matching any character (dot).
 **/
ReSubExpression r_re_dot();

/**
 * \brief Construct a sub-expression matching a single character.
 **/
ReSubExpression r_re_letter(uni_char letter);

/**
 * \brief Match an NFA to a string.
 * \param[in] greedy If this is set to true, will try to match as many chars
 * as possible. Otherwise, shortest match will be returned.
 * \return true if match succeeded. *id is set to the id of the match that was
 * made. (This is only useful in the lexer.)
 **/
bool r_re_match(char* s, NFANode* pattern, bool greedy, int* id, int* length);

/**
 * \brief sub-expression := sub-expression +
 **/
ReSubExpression r_re_plus(ReSubExpression expr);

/**
 * \brief sub-expression := sub-expression ?
 **/
ReSubExpression r_re_question(ReSubExpression expr);

/**
 * \brief Route a linked list of outputs to a given node.
 **/
void r_re_route(NFANode* output, NFANode* target);

/**
 * \brief sub-expression := sub-expression *
 **/
ReSubExpression r_re_star(ReSubExpression expr);

#endif /* R_RE_H */
